package com.csu.letaobackend.serviceM.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csu.letaobackend.bean.*;
import com.csu.letaobackend.commom.CommonResponse;
import com.csu.letaobackend.dto.Attr;
import com.csu.letaobackend.dto.ItemVO2;
import com.csu.letaobackend.persistence.*;
import com.csu.letaobackend.serviceM.CatalogMService;
import com.csu.letaobackend.vo.*;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@MapperScan("com.csu.letaobackend.persistence")
public class CatalogMServiceImpl implements CatalogMService {

      @Autowired
      CategoryDao categoryDao;

      @Autowired
      ProductDao productDao;

      @Autowired
      ItemDao itemDao;

      @Autowired
      PictureDao pictureDao;

      @Autowired
      ItemattrDao itemattrDao;

      @Autowired
      ItemevalDao itemevalDao;

      @Autowired
      AttributesDao attributesDao;

      @Autowired
      AttrvaluesDao attrvaluesDao;

      @Autowired
      SpecialofferDao specialofferDao;

      @Autowired
      FavoriteitemDao favoriteitemDao;

      @Autowired
      ShopDao shopDao;

      @Autowired
      SwiperitemDao swiperitemDao;

      @Autowired
      BrowsingrecordDao browsingrecordDao;


      @Override
      public CommonResponse<List<CategoryVO>> getCategories() {
            List<Category> categoryList = categoryDao.selectList(null);
            List<CategoryVO> categoryVOList = new ArrayList<>();
            ;
            for (Category category : categoryList) {
                  categoryVOList.add(entityToVO(category));
            }
            return CommonResponse.createForSuccess(categoryVOList);
      }

      @Override
      public CommonResponse<List<ProductVO>> getProductsByCategoryId(int categoryId) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("categoryId", categoryId);
            List<Product> productList = productDao.selectList(queryWrapper);
            List<ProductVO> productVOList = new ArrayList<>();
            for (Product product : productList) {
                  productVOList.add(entityToVO(product));
            }
            return CommonResponse.createForSuccess(productVOList);
      }

      @Override
      public CommonResponse<List<ItemVO>> getItemsByProductId(int productId, String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("productId", productId);
            List<Item> itemList = itemDao.selectList(queryWrapper);
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemList) {
                  itemVOList.add(entityToVO(item, username));
            }
            return CommonResponse.createForSuccess(itemVOList);
      }

      @Override
      public CommonResponse<List<ItemVO>> getItemsByProductId(int productId, int sortby, String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("productId", productId);
            queryWrapper = sortWrapper(queryWrapper, sortby);

            List<Item> itemList = itemDao.selectList(queryWrapper);
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemList) {
                  itemVOList.add(entityToVO(item, username));
            }
            return CommonResponse.createForSuccess(itemVOList);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> getItemsPages(int productId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("productId", productId);
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }

            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> getAllItems(int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }

            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<List<ItemAttrVO>> getAttrByItemId(int itemId) {
            List<ItemAttrVO> itemAttrVOList = new ArrayList<>();

            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("itemId", itemId);
            queryWrapper.orderByAsc("attrId");
            List<Itemattr> itemattrList = itemattrDao.selectList(queryWrapper);

            List<Itemattr> temp = new ArrayList<>();
            int flag = 0;
            for (int i = 0; i < itemattrList.size(); ) {
                  while (i < itemattrList.size() && flag == itemattrList.get(i).getAttrid()) {
                        temp.add(itemattrList.get(i));
                        i++;
                  }
                  if (temp.size() != 0)
                        itemAttrVOList.add(entityToVO(temp));
                  temp.clear();
                  if (i < itemattrList.size())
                        flag = itemattrList.get(i).getAttrid();
            }
            return CommonResponse.createForSuccess(itemAttrVOList);
      }

      @Override
      public CommonResponse<List<ItemVO>> getItemsByShopId(int shopId, int sortby, String username) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("shopId", shopId);
            queryWrapper = sortWrapper(queryWrapper, sortby);

            List<Item> itemList = itemDao.selectList(queryWrapper);
            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemList) {
                  itemVOList.add(entityToVO(item, username));
            }
            return CommonResponse.createForSuccess(itemVOList);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> getItemsPagesByShopId(int shopId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("shopId", shopId);
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }
            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> searchItemsPages(String keyword, int categoryId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.like("description", keyword);
            if (categoryId != 0) {
                  QueryWrapper queryWrapper1 = new QueryWrapper();
                  queryWrapper1.eq("categoryId", categoryId);
                  List<Product> productList = productDao.selectList(queryWrapper1);
                  List<Integer> list = new ArrayList<>();
                  for (Product product : productList) {
                        list.add(product.getId());
                  }
                  queryWrapper.in("productId", list);
            }
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }
            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse<IPage<ItemVO>> searchItemsPagesByProduct(String keyword, int productId, int sortby, int currentPage, int pageSize, String username) {
            IPage<Item> itemPage = new Page<>(currentPage, pageSize);

            QueryWrapper<Shop> queryWrapper1 = new QueryWrapper();
            queryWrapper1.like("name",keyword);
            List<Integer> list=new ArrayList<>();
            for (Shop shop : shopDao.selectList(queryWrapper1)) {
                  list.add(shop.getShopid());
            }
            QueryWrapper<Item> queryWrapper = new QueryWrapper<Item>();
            queryWrapper.eq("productId", productId);
            queryWrapper.and(Wrapper->Wrapper.like("description",keyword).or().in("shopid",list));//联合查询
            queryWrapper = sortWrapper(queryWrapper, sortby);
            itemDao.selectPage(itemPage, queryWrapper);

            List<ItemVO> itemVOList = new ArrayList<>();
            for (Item item : itemPage.getRecords()) {
                  itemVOList.add(entityToVO(item, username));
            }
            IPage<ItemVO> itemVOPage = new Page<>(currentPage, pageSize);
            itemVOPage.setTotal(itemPage.getTotal());
            itemVOPage.setRecords(itemVOList);

            return CommonResponse.createForSuccess(itemVOPage);
      }

      @Override
      public CommonResponse additem(ItemVO2 itemVO2) {
            Item item = VOtoEntity(itemVO2);
            itemDao.insert(item);
            for(Attr attr:itemVO2.getItemattrlist()){
                  for(int valueid:attr.getAttrvalsid()){
                        Itemattr itemattr = new Itemattr();
                        itemattr.setItemid(item.getId());
                        itemattr.setAttrid(attr.getAttrid());
                        if(valueid==0){
                              continue;
                        }
                        itemattr.setValueid(valueid);
                        itemattr.setRate(1);
                        itemattr.setPictureid(1);
                        itemattrDao.insert(itemattr);
                  }
            }
            return CommonResponse.createForSuccess("新增商品成功");
      }

      @Override
      public CommonResponse deleteitem(int itemid) {

            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("id",itemid);
            itemDao.delete(queryWrapper);
            return CommonResponse.createForSuccess("删除成功");
      }

      @Override
      public CommonResponse updateitem(Item item) {
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id",item.getId());
            itemDao.update(item,updateWrapper);
            return CommonResponse.createForSuccessMessage("更新成功");
      }

      @Override
      public CommonResponse updatestatus(int itemid, int available, int isnew, int isrecommend) {
            UpdateWrapper<Item> updateWrapper = new UpdateWrapper<Item>();
            updateWrapper.eq("itemid",itemid).set("available",available).set("isnew",isnew).set("isrecommend",isrecommend);
            itemDao.update(null,updateWrapper);
            return CommonResponse.createForSuccessMessage("更新成功");
      }



      private Item VOtoEntity(ItemVO2 itemVO2){
            Item item = new Item();
            item.setId(getMaxItemId()+1);
            item.setProductid(itemVO2.getProductid());
            item.setShopid(itemVO2.getShopid());
            item.setPrice(itemVO2.getPrice());
            item.setStock(itemVO2.getStock());
            item.setPictureid(itemVO2.getPictureid());
            item.setDescription(itemVO2.getDescription());
            item.setVideoid(0);
            item.setAvailable(itemVO2.getAvailable());
            item.setIsnew(itemVO2.getIsnew());
            item.setIsrecommend(itemVO2.getIsrecommend());
            return item;
      }

      private int getMaxItemId() {
            List<Integer> list = new ArrayList<>();
            for (Item item: itemDao.selectList(null)) {
                  list.add(item.getId());
            }
            if (list.size() == 0)
                  return 0;
            return Collections.max(list);
      }

      private QueryWrapper sortWrapper(QueryWrapper queryWrapper, int sortby) {
            switch (sortby) {
                  case 0:
                        queryWrapper.orderByAsc("id");
                        break;
                  case 1:
                        queryWrapper.orderByAsc("description");
                        break;
                  case 2:
                        queryWrapper.orderByDesc("description");
                        break;
                  case 3:
                        queryWrapper.orderByAsc("price");
                        break;
                  case 4:
                        queryWrapper.orderByDesc("price");
                        break;
                  case 5:
                        queryWrapper.orderByAsc("stock");
                        break;
                  case 6:
                        queryWrapper.orderByDesc("stock");
                        break;
            }
            return queryWrapper;
      }

      private SwiperitemVO entityToVO(Swiperitem swiperitem) {
            Picture picture = pictureDao.selectById(swiperitem.getPictureid());
            SwiperitemVO swiperitemVO = new SwiperitemVO();
            swiperitemVO.setItemid(swiperitem.getItemid());
            swiperitemVO.setPictureid(swiperitem.getPictureid());
            swiperitemVO.setSrc(picture.getSrc());
            swiperitemVO.setDescription(swiperitem.getDescription());
            swiperitemVO.setSlogan(swiperitem.getSlogan());
            swiperitemVO.setStarttime(swiperitem.getStarttime());
            swiperitemVO.setEndtime(swiperitem.getEndtime());
            swiperitemVO.setAvailable(swiperitem.getAvailable());
            swiperitemVO.setClick(swiperitem.getAvailable());
            Item item = itemDao.selectById(swiperitem.getItemid());
            swiperitemVO.setShopname(shopDao.selectById(item.getShopid()).getName());
            return swiperitemVO;
      }

      private BrowsingrecordVO entityToVO(Browsingrecord browsingrecord) {
            BrowsingrecordVO browsingrecordVO = new BrowsingrecordVO();
            browsingrecordVO.setUsername(browsingrecord.getUsername());
            browsingrecordVO.setTime(browsingrecord.getTime());
            browsingrecordVO.setItemid(browsingrecord.getItemid());
            int pictureid = itemDao.selectById(browsingrecord.getItemid()).getPictureid();
            browsingrecordVO.setSrc(pictureDao.selectById(pictureid).getSrc());

            return browsingrecordVO;
      }

      private CategoryVO entityToVO(Category category) {
            Picture picture = pictureDao.selectById(category.getPictureid());
            CategoryVO categoryVO = new CategoryVO();
            categoryVO.setId(category.getId());
            categoryVO.setName(category.getName());
            categoryVO.setPictureid(category.getPictureid());
            categoryVO.setSrc(picture.getSrc());
            return categoryVO;
      }

      private ProductVO entityToVO(Product product) {
            Picture picture = pictureDao.selectById(product.getPictureid());
            ProductVO productVO = new ProductVO();
            productVO.setId(product.getId());
            productVO.setName(product.getName());
            productVO.setCategoryid(product.getCategoryid());
            productVO.setPictureid(product.getPictureid());
            productVO.setSrc(picture.getSrc());
            return productVO;
      }

      private ItemVO entityToVO(Item item, String username) {
            Picture picture = pictureDao.selectById(item.getPictureid());
            double star = getAvgStar(item);
            ItemVO itemVO = new ItemVO();
            itemVO.setId(item.getId());
            itemVO.setProductid(item.getProductid());
            itemVO.setShopid(item.getShopid());
            itemVO.setShopname(shopDao.selectById(item.getShopid()).getName());
            itemVO.setPrice(item.getPrice());
            itemVO.setStock(item.getStock());
            itemVO.setPictureid(item.getPictureid());
            itemVO.setDescription(item.getDescription());
            itemVO.setVideoid(item.getVideoid());
            itemVO.setAvailable(item.getAvailable());
            itemVO.setIsnew(item.getIsnew());
            itemVO.setIsrecommend(item.getIsrecommend());

            itemVO.setSrc(picture.getSrc());
            itemVO.setStar(String.valueOf(star));
            if (username == null)
                  itemVO.setIsFavorite(0);
            else {
                  QueryWrapper queryWrapper = new QueryWrapper();
                  queryWrapper.eq("username", username);
                  queryWrapper.eq("itemid", item.getId());
                  if (favoriteitemDao.selectOne(queryWrapper) != null)
                        itemVO.setIsFavorite(1);
                  else
                        itemVO.setIsFavorite(0);
            }
            return itemVO;
      }

      private ItemAttrVO entityToVO(List<Itemattr> itemattrList) {
            ItemAttrVO itemAttrVO = new ItemAttrVO();
            Itemattr itemattr = itemattrList.get(0);
            itemAttrVO.setItemId(itemattr.getItemid());
            itemAttrVO.setAttrname(attributesDao.selectById(itemattr.getAttrid()).getAttrname());
            itemAttrVO.setPrice(itemDao.selectById(itemattr.getItemid()).getPrice());
            if (specialofferDao.selectById(itemattr.getItemid()) != null)
                  itemAttrVO.setSpecialrate(specialofferDao.selectById(itemattr.getItemid()).getRate());
            else
                  itemAttrVO.setSpecialrate(1);
            itemAttrVO.setStock(itemDao.selectById(itemattr.getItemid()).getStock());
            List<AttrVO> attrVOList = new ArrayList<>();
            for (Itemattr itemattr1 : itemattrList) {
                  attrVOList.add(entityToVO(itemattr1));
            }
            itemAttrVO.setAttrList(attrVOList);
            return itemAttrVO;
      }

      private AttrVO entityToVO(Itemattr itemattr) {
            AttrVO attrVO = new AttrVO();
            attrVO.setAttrvalue(attrvaluesDao.selectById(itemattr.getValueid()).getAttrvalue());
            attrVO.setRate(itemattr.getRate());
            attrVO.setSrc(pictureDao.selectById(itemattr.getPictureid()).getSrc());
            return attrVO;
      }

      private double getAvgStar(Item item) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("itemid", item.getId());
            List<Itemeval> itemevalList = itemevalDao.selectList(queryWrapper);
            double star = 0.0;
            double totalStar = 0.0;
            for (Itemeval itemeval : itemevalList) {
                  totalStar += itemeval.getStar();
            }
            if (itemevalList.size() > 0) {
                  star = new BigDecimal(totalStar / itemevalList.size()).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            return star;
      }


      @Override
      public CommonResponse addCategory(Category category) {
            category.setId(getMaxCategoryId()+1);
            categoryDao.insert(category);
            return CommonResponse.createForSuccess("添加一级分类成功");
      }

      @Override
      public CommonResponse updateCategory(Category category) {
            categoryDao.updateById(category);
            return CommonResponse.createForSuccess("更新一级分类成功");
      }

      @Override
      public CommonResponse addProduct(Product product) {
            product.setId(getMaxProductId()+1);
            productDao.insert(product);
            return CommonResponse.createForSuccess("添加二级分类成功");
      }

      @Override
      public CommonResponse updateProduct(Product product) {
            productDao.updateById(product);
            return CommonResponse.createForSuccess("更新二级分类成功");
      }

      private int getMaxCategoryId() {
            List<Integer> list = new ArrayList<>();
            for (Category category: categoryDao.selectList(null)) {
                  list.add(category.getId());
            }
            if (list.size() == 0)
                  return 0;
            return Collections.max(list);
      }

      private int getMaxProductId() {
            List<Integer> list = new ArrayList<>();
            for (Product product: productDao.selectList(null)) {
                  list.add(product.getId());
            }
            if (list.size() == 0)
                  return 0;
            return Collections.max(list);
      }

      @Override
      public CommonResponse<List<Attributes>> getAttributes() {
            List<Attributes> attributes = attributesDao.selectList(null);

            return CommonResponse.createForSuccess(attributes);
      }

      @Override
      public CommonResponse<List<Attrvalues>> getAttrvalues(int attrid) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("attrid",attrid);
            List<Attrvalues> attrvaluesList= attrvaluesDao.selectList(queryWrapper);
            return CommonResponse.createForSuccess(attrvaluesList);
      }
}
